Class - Instance Duality
Back in high-school physics we learned about the "wave-particle duality" of light. Sometimes it acts like a particle (going through a small aperture) and sometimes it acts like a wave (rainbows, etc.) The behavior of Testcase Classes (page X) sometimes reminds me of this. Let me explain why.
Developers new to xUnit often ask "Why is the class we subclass called TestCase when we have several Test Methods (page X) on it? Shouldn't it be called TestSuite?" This question makes a lot of sense when we are focussed primarily on the view of the class when we are writing the test code as opposed to when we are running the code.
When we are writing our test code we are focused on the Test Methods. The Testcase Class is primarily just a place to put the methods. About the only time we think of objects is when we use Implicit Setup (page X) and need to create fields (instance variables) to hold them between the invocation of the setUp method and when they are used in the Test Method. When a developer new to xUnit test automation is writing their first tests, they tend to code by example. Following an existing example is good for getting something working quickly but it doesn't necessarily help understand what is really going on.
At runtime, the xUnit framework typically creates one instance of the Testcase Class for each Test Method. The Testcase Class acts as a Test Suite Factory (see Test Enumeration on page X) that builds a Test Suite Object (page X) containing all the instances of itself, one for each Test Method. Now, it's not very often that we see a static method on a class returning an instance of another class containing many instances of itself. If this wasn't odd enough, the fact that xUnit reports the test failures using the Test Method name can be enough to obscure from many test automaters that there are "objects inside".
When we examine the object relationships at run time, things become a bit more clear. The Test Suite Object returned by the Test Suite Factory contains one or more Testcase Objects (page X). So far, so good. These object are each an instance of our Testcase Class. Each instance is configured to run one of the Test Methods. More importantly, each will run a different Test Method. (How this happens is described in more detail in Test Discovery (page X).) So each instance of our Testcase Class is indeed a test case. The Test Methods are just how we tell each instance what it should test.
Further Reading
Martin Fowler has a great piece on his blog about this called "JUnit New Instance"[JNI].
Copyright © 2003-2008 Gerard Meszaros all rights reserved